package com.ourteam.system.api;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.ourteam.frame.controller.AbstractServiceController;
import com.ourteam.frame.web.AbstractSearchHelper;
import com.ourteam.frame.web.AbstractStaticArraySearchHelper;
import com.ourteam.frame.web.ApplicationModel;
import com.ourteam.frame.web.DataAccessHelper;
import com.ourteam.frame.web.GridBean;
import com.ourteam.frame.web.OperationResult;
import com.ourteam.system.dao.ISysUserDAO;
import com.ourteam.system.dao.SysUser;
import com.ourteam.system.dao.SysUserDAOQueryBean;
import com.ourteam.system.dao.SysUserDepartmentRelateDAOQueryBean;
import com.ourteam.system.dao.SysUserRoleRelateDAOQueryBean;
import com.ourteam.system.domain.SystemUser;
import com.ourteam.system.domain.SystemUserDepartmentRelateBean;
import com.ourteam.system.domain.SystemUserPassword;
import com.ourteam.system.domain.SystemUserRoleRelate;
import com.ourteam.system.service.ISysDepartmentService;
import com.ourteam.system.service.ISysUserService;

@RestController
@CrossOrigin
@RequestMapping("/api/SYSTEM/ACCOUNT")
public class SystemAccountAPI extends AbstractServiceController {

	@Autowired
	private ISysUserService sysUserService;
	@Autowired
	private ISysDepartmentService sysDepartmentService;

	@RequestMapping("/getSysAccountById")
	public SystemUser getSysAccountById(@RequestParam(value = "id", required = true) long id,
			HttpServletRequest request, Model model) throws Exception {

		return sysUserService.getSysUserById(id);

	}

	@RequestMapping("/saveSysAccount")
	@ResponseBody
	public SystemUser saveSysAccount(@ModelAttribute SystemUser systemUser, HttpServletRequest request, Model model)
			throws Exception {

		systemUser.setOperatorId(getLoginUserId());
		systemUser.setModifyTime(new Date());

		if (systemUser.getId() != 0) {
			sysUserService.modifySysUser(systemUser);
		} else {
			sysUserService.createSysUser(systemUser);
		}

		return systemUser;
	}

	@RequestMapping("/searchSysAccounts")
	public GridBean searchSysAccounts(@RequestParam String search, HttpServletRequest request, Model model)
			throws Exception {

		if (StringUtils.isEmpty(search)) {
			return new GridBean();
		}

		SystemAccountSearchModel searchModel = new SystemAccountSearchModel();

		searchModel.setAccount(search);

		AbstractSearchHelper<SysUserDAOQueryBean, SystemAccountSearchModel> searchHelper = new AbstractSearchHelper<SysUserDAOQueryBean, SystemAccountSearchModel>(
				searchModel) {

			@Override
			protected int queryCount(SysUserDAOQueryBean queryBean) throws Exception {
				return sysUserService.getSysUserCount(queryBean);
			}

			@Override
			protected Object[] queryData(SysUserDAOQueryBean queryBean) throws Exception {
				return sysUserService.getSysUsers(queryBean);
			}

			@Override
			protected SysUserDAOQueryBean createQueryBean() {
				return new SysUserDAOQueryBean();
			}
		};

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/querySysAccounts")
	@ResponseBody
	public GridBean querySysAccounts(@ModelAttribute SystemAccountSearchModel searchModel, HttpServletRequest request,
			Model model) throws Exception {

		DataAccessHelper<SysUser, SysUserDAOQueryBean, SystemAccountSearchModel> searchHelper = new DataAccessHelper<SysUser, SysUserDAOQueryBean, SystemAccountSearchModel>(
				searchModel, ISysUserDAO.class);

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/querySysAccountList")
	@ResponseBody
	public GridBean querySysAccountList(@ModelAttribute SystemAccountSearchModel searchModel,
			HttpServletRequest request, Model model) throws Exception {

		AbstractSearchHelper<SysUserDAOQueryBean, SystemAccountSearchModel> searchHelper = new AbstractSearchHelper<SysUserDAOQueryBean, SystemAccountSearchModel>(
				searchModel) {

			@Override
			protected int queryCount(SysUserDAOQueryBean queryBean) throws Exception {
				return sysUserService.getSysUserCount(queryBean);
			}

			@Override
			protected Object[] queryData(SysUserDAOQueryBean queryBean) throws Exception {
				return sysUserService.getSysUsers(queryBean);
			}

			@Override
			protected SysUserDAOQueryBean createQueryBean() {
				return new SysUserDAOQueryBean();
			}
		};

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/querySysAccountRoleList")
	@ResponseBody
	public GridBean querySysAccountRoles(final @ModelAttribute SystemAccountRoleSearchModel searchModel,
			HttpServletRequest request, Model model) throws Exception {

		AbstractStaticArraySearchHelper<SysUserRoleRelateDAOQueryBean, SystemAccountRoleSearchModel> searchHelper = new AbstractStaticArraySearchHelper<SysUserRoleRelateDAOQueryBean, SystemAccountRoleSearchModel>(
				searchModel) {

			@Override
			protected SysUserRoleRelateDAOQueryBean createQueryBean() {
				return new SysUserRoleRelateDAOQueryBean();
			}

			@Override
			protected Object[] getData(SystemAccountRoleSearchModel searchModel) throws Exception {
				return sysUserService.getSysUserAuthorities(searchModel.getSysAccountId());
			}
		};

		return searchHelper.doSearch(request);

	}

	@RequestMapping("/deleteSysAccount")
	@ResponseBody
	public String deleteSysAccounts(@RequestParam(value = "ids") long[] ids, HttpServletRequest request, Model model)
			throws Exception {

		SysUserDepartmentRelateDAOQueryBean queryBean = new SysUserDepartmentRelateDAOQueryBean();
		queryBean.createCriteria().andSysUserIdIn(ids);
		SystemUserDepartmentRelateBean[] relate = sysDepartmentService.querySystemUserDepartments(queryBean);
		long[] depdeleteIds = new long[relate.length];
		for (int i = 0; i < relate.length; i++) {
			depdeleteIds[i] = relate[i].getId();
		}

		sysDepartmentService.deleteSystemUserDepartments(depdeleteIds);

		sysUserService.deleteSysUsers(ids, getLoginUserId());

		return "success";
	}

	@RequestMapping("/lockedSysAccount")
	@ResponseBody
	public String lockedSysAccount(@RequestParam(value = "ids[]") long[] ids, HttpServletRequest request, Model model)
			throws Exception {

		for (int i = 0; i < ids.length; i++) {

			SystemUser sysUser = this.sysUserService.getSysUserById(ids[i]);

			sysUser.setStatus("LOCKED");

			sysUserService.modifySysUser(sysUser);
		}

		return "success";
	}

	@RequestMapping("/addSysAccountRoles")
	@ResponseBody
	public String addSysAccountRoles(@RequestParam(value = "sysAccountId") long sysAccountId,
			@RequestParam(value = "sysRoleIds") String sysRoleIds, HttpServletRequest request, Model model)
			throws Exception {

		String[] roleIds = StringUtils.split(sysRoleIds, ",");

		SystemUserRoleRelate[] addUserRoleRelates = new SystemUserRoleRelate[roleIds.length];

		for (int i = 0; i < addUserRoleRelates.length; i++) {
			addUserRoleRelates[i] = new SystemUserRoleRelate();

			addUserRoleRelates[i].setUserId(sysAccountId);

			addUserRoleRelates[i].setRoleId(Long.parseLong(roleIds[i]));
		}

		SystemUserRoleRelate[] userRoleRelates = sysUserService.getSysUserAuthorities(sysAccountId);

		sysUserService.setSysUserAuthorities(sysAccountId,
				(SystemUserRoleRelate[]) ArrayUtils.addAll(addUserRoleRelates, userRoleRelates));

		return "success";
	}

	@RequestMapping("/setSysAccountRoles")
	@ResponseBody
	public String setSysAccountRoles(@RequestParam(value = "sysAccountIds[]") long[] sysAccountIds,
			@RequestParam(value = "sysRoleIds[]") long[] sysRoleIds, HttpServletRequest request, Model model)
			throws Exception {

		for (int i = 0; i < sysAccountIds.length; i++) {

			long sysAccountId = sysAccountIds[i];

			SystemUserRoleRelate[] addUserRoleRelates = new SystemUserRoleRelate[sysRoleIds.length];

			for (int j = 0; j < addUserRoleRelates.length; j++) {
				addUserRoleRelates[j] = new SystemUserRoleRelate();

				addUserRoleRelates[j].setUserId(sysAccountId);

				addUserRoleRelates[j].setRoleId(sysRoleIds[j]);
			}

			sysUserService.setSysUserAuthorities(sysAccountId, addUserRoleRelates);
		}

		return "success";
	}

	@RequestMapping("/setSysAccountStatus")
	@ResponseBody
	public String setSysAccountStatus(@RequestParam(value = "sysAccountIds[]") long[] sysAccountIds,
			@RequestParam String userStatus, HttpServletRequest request, Model model) throws Exception {

		for (int i = 0; i < sysAccountIds.length; i++) {

			long sysAccountId = sysAccountIds[i];

			SystemUser systemUser = sysUserService.getSysUserById(sysAccountId);

			systemUser.setUserStatus(userStatus);

			sysUserService.modifySysUser(systemUser);
		}

		return "success";
	}

	@RequestMapping("/addSysAccountRoleGroups")
	@ResponseBody
	public String addSysAccountRoleGroups(@RequestParam(value = "sysAccountId") long sysAccountId,
			@RequestParam(value = "sysRoleGroupIds") String sysRoleGroupIds, HttpServletRequest request, Model model)
			throws Exception {

		String[] roleIds = StringUtils.split(sysRoleGroupIds, ",");

		SystemUserRoleRelate[] addUserRoleRelates = new SystemUserRoleRelate[roleIds.length];

		for (int i = 0; i < addUserRoleRelates.length; i++) {
			addUserRoleRelates[i] = new SystemUserRoleRelate();

			addUserRoleRelates[i].setUserId(sysAccountId);

			addUserRoleRelates[i].setRoleId(Long.parseLong(roleIds[i]));
		}

		SystemUserRoleRelate[] userRoleRelates = sysUserService.getSysUserAuthorities(sysAccountId);

		sysUserService.setSysUserAuthorities(sysAccountId,
				(SystemUserRoleRelate[]) ArrayUtils.addAll(addUserRoleRelates, userRoleRelates));

		return "success";

	}

	@RequestMapping("/removeSysAccountRoles")
	@ResponseBody
	public String removeSysAccountRoles(@RequestParam(value = "sysAccountId") long sysAccountId,
			@RequestParam(value = "sysAccountRoleIds") String ids, HttpServletRequest request, Model model)
			throws Exception {

		String[] roleIds = StringUtils.split(ids, ",");

		List<SystemUserRoleRelate> userRoleRelates = new ArrayList<SystemUserRoleRelate>();

		SystemUserRoleRelate[] currentUserRoleRelates = sysUserService.getSysUserAuthorities(sysAccountId);

		boolean canAdd = true;
		for (int i = 0; i < currentUserRoleRelates.length; i++) {
			SystemUserRoleRelate systemUserRoleRelate = currentUserRoleRelates[i];
			for (int j = 0; j < roleIds.length; j++) {
				long id = Long.parseLong(roleIds[j]);
				if (systemUserRoleRelate.getId() == id) {
					canAdd = false;
					break;
				}
			}
			if (canAdd == true) {
				userRoleRelates.add(systemUserRoleRelate);
			}

			canAdd = true;

		}

		sysUserService.setSysUserAuthorities(sysAccountId,
				userRoleRelates.toArray(new SystemUserRoleRelate[userRoleRelates.size()]));

		return "success";
	}

	@RequestMapping("/changePsw")
	@ResponseBody
	public String doChangePsw(@RequestParam(value = "sysAccountId", required = true) long accountId,
			@RequestParam(value = "newPsw", required = true) String newPWD, HttpServletRequest request, Model model)
			throws Exception {

		SystemUser user = this.sysUserService.getSysUserById(accountId);
		if (null == user) {
			return "error";
		}

		SystemUserPassword aSystemUserPassword = new SystemUserPassword();
		aSystemUserPassword.setAccount(user.getAccount());
		aSystemUserPassword.setPassword(newPWD);
		this.sysUserService.changeUserPassword(aSystemUserPassword);

		return "success";

	}

	@RequestMapping("/uploadUserPhoto")
	@ResponseBody
	public OperationResult uploadUserPhoto(@RequestParam(value = "photoFile") MultipartFile[] files,
			HttpServletRequest request, HttpServletResponse response) throws Exception {

		Subject subject = SecurityUtils.getSubject();

		ApplicationModel appModel = (ApplicationModel) subject.getPrincipal();

		String account = appModel.getUserAccount();

		SystemUser user = this.sysUserService.getSysUserByAccount(account);

		for (MultipartFile fileItem : files) {

			if (fileItem.isEmpty()) {
				continue;
			}

			try {

				String imageStr = Base64.encodeBase64String(fileItem.getBytes());

				user.setPhotoPath("data:image/" + FilenameUtils.getExtension(fileItem.getOriginalFilename())
						+ ";base64," + imageStr);

				this.sysUserService.modifySysUser(user);

				appModel.setUserPhoto(user.getPhotoPath());

			} catch (Exception e) {
				e.printStackTrace();
				return new OperationResult(true, e.getMessage(), null);
			}

		}

		return OperationResult.SUCCESS_RESULT;

	}

}
